#pragma once
#include<string>
using namespace std; 
#include<queue>
#include"connection.h"
#include<mutex>
#include<condition_variable>
#include<atomic>
#include<thread>
#include<memory>
#include<functional>
/*
实现连接池功能
*/
class ConnectionPool
{
public:
    static ConnectionPool *getConnectionPool();
    
    //给外部提供接口，从连接池中获取一个可用的空闲连接：消费者线程
    shared_ptr<Connection> getConnection();
    //用户使用完连接，智能指针出作用域，析构连接，此时需要重新定义删除器让它将连接归还池中而不析构

private:
    ConnectionPool();//构造函数私有化

    bool loadConfigFile();//从配置文件加载配置项
   
    //运行在独立的线程中，专门负责生成新连接:生产者线程
    void produceConnectionTask();//将线程函数写成类的成员方法最大的好处就是可以方便的访问类的成员变量

    //启动一个新的定时线程，扫描超过maxIdleTime时间的空闲连接，进行多于的连接回收
    void scannerConnectionTask();

    string _ip;          // mysql ip
    unsigned short _port;//端口号
    string _username;//用户名字
    string _password;//用户密码
    string _dbname;//数据库名字
    int _initSize; // 初始连接数
    int _maxSize;//最大连接数
    int _maxIdleTime;//最大空闲时间
    int _connectionTimeout;//超时时间

    queue<Connection *> _connectionque;//存储连接的队列
    mutex _queMutex;//维护连接队列的线程安全互斥锁
    atomic_int _conCount;//创建连接的数量

    condition_variable cv;//设置条件变量，用于连接生产线程和消费线程的通信
};